﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace DisposeStudy
{
    class Program
    {
        static void Main()
        {
            {
                var res = new CustomResourceOwner(IntPtr.Zero);
                res.DoSomeThing();
            }
        }
    }

    class ResourceOwnerBase : IDisposable
    {
        private bool _disposed;
        private readonly FileStream _fileStream;
        private IntPtr _handle;

        protected ResourceOwnerBase(IntPtr handle)
        {
            _handle = handle;
            _fileStream = File.OpenRead(@"E:\Coding\HappyStudy\DisposeStudy\DisposeStudy\Program.cs");
        }

        protected bool Disposed
        {
            get { return _disposed; }
        }

        public void Dispose()
        {
            Dispose(true);

            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (Disposed)
            {
                if (disposing)
                {
                    _fileStream.Dispose();
                }

                CloseHandle(_handle);
                _handle = IntPtr.Zero;

                _disposed = true;
            }
        }

        ~ResourceOwnerBase()
        {
            Console.WriteLine("父类析构方法！");
            Dispose(false);
        }

        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);
    }

    sealed class CustomResourceOwner : ResourceOwnerBase
    {
        public CustomResourceOwner(IntPtr handle)
            : base(handle)
        {
        }

        public void DoSomeThing()
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("资源已经消耗了，不能执行此操作！");
            }

            Console.WriteLine("随便做点工作！");
        }

        ~CustomResourceOwner()
        {
            Console.WriteLine("子类析构方法！");
        }
    }
}
